#pragma once

#include "LinkedList.h"
#include "BufChunkMgr.h"

template <typename T, typename CLock = CFakeLock>
class CBufList : public CLinkedList<T, CLock>
{
    typedef typename CLinkedList<T, CLock>::Node BaseNode;

public:
    struct ListNode : public CLinkedList<T, CLock>::Node
    {
        friend class CBufList;

    private:
        void *operator new(size_t, void *ptr) _GLIBCXX_USE_NOEXCEPT { return ptr; }
        void operator delete(void *ptr) {}
    };

public:
    CBufList()
    {
        m_pChunkMgr = nullptr;
    }

    BaseNode *NewNode()
    {
        void *ptr = nullptr;

        if (nullptr == m_pChunkMgr)
            return nullptr;

        ptr = m_pChunkMgr->Alloc(sizeof(ListNode));

        return new (ptr) ListNode();
    }

    BaseNode *NewNode(int iExtLen)
    {
        void *ptr = nullptr;

        if (nullptr == m_pChunkMgr)
            return nullptr;

        ptr = m_pChunkMgr->Alloc(sizeof(ListNode) + iExtLen);

        return new (ptr) ListNode();
    }

    BaseNode *NewNode(void *ptr)
    {
        if (nullptr == ptr)
            return nullptr;

        return new (ptr) ListNode();
    }

    void DeleteNode(BaseNode *pNode)
    {
        // 自动调用Node及其父结构的析构函数,父结构需虚析构函数
        delete (ListNode *)pNode;
    }

    void SetChunkMgr(CBufChunkMgr<CLock> *pChunkMgr)
    {
        m_pChunkMgr = pChunkMgr;
    }

private:
    CBufChunkMgr<CLock> *m_pChunkMgr;
};
